package com.example.sourcecodelearning.modules.zendesk;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.example.framework.common.exception.ServiceException;
import com.example.framework.web.core.util.RestUtils;
import com.example.module.system.enums.ErrorCodeConstants;
import com.example.sourcecodelearning.modules.zendesk.dto.WebSupportRmaRequest;
import jakarta.validation.constraints.NotEmpty;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHeaders;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class ZendeskService {

    private final String domain = "https://xxxxx.zendesk.com";
    private final String email = "xxx@qq.com";
    private final String apiToken = "xxxxxxxxx";

    private final String rmaMailTextUrl = ZendeskService.class.getResource("/RmaMail.txt").getPath();
    private final String rmaSubject = "RMA info";

    public String uploadFile(MultipartFile multipartFile) {
        if (Objects.isNull(multipartFile)) {
            throw ServiceException.of(ErrorCodeConstants.FILE_IS_NEEDED);
        }
        String originalFilename = multipartFile.getOriginalFilename();
        if (ObjectUtil.isEmpty(originalFilename)) {
            throw ServiceException.of(ErrorCodeConstants.FILE_UNAVAILABLE);
        }

        File file = new File(originalFilename);
        boolean created = false;
        try {
            if (!file.exists()) {
                created = file.createNewFile();
                if (!created) {
                    log.error("Could not create the file {}", originalFilename);
                    throw ServiceException.of(ErrorCodeConstants.FILE_UPLOAD_FAILED);
                }
            }
            FileCopyUtils.copy(multipartFile.getBytes(), file);

            String url = domain + "/api/v2/uploads";

            Map<String, String> params = new HashMap<>() {{
                put("filename", originalFilename);
            }};
            JSONObject response = RestUtils.postFile(url, getAuthHeaders(), multipartFile.getContentType(), params, file, JSONObject.class);
            return response.getJSONObject("upload").getStr("token");
        } catch (IOException | NullPointerException e) {
            throw ServiceException.of(ErrorCodeConstants.FILE_UPLOAD_FAILED);
        } finally {
            // 删除此临时文件
            if (created) {
                boolean delete = file.delete();
                if (!delete) {
                    log.warn("Could not delete {}", file);
                }
            }
        }
    }

    public JSONObject createTicket(WebSupportRmaRequest model) {
        // 有附件先上传
        MultipartFile file = model.getFile();
        String token = null;
        if (Objects.nonNull(file)) {
            token = uploadFile(file);
        }

        String url = domain + "/api/v2/requests";

        String recipient = getRecipientByRegionCode(model.getRegionCode());

        String finalToken = token;
        Map<String, Object> requestBody = new HashMap<>() {{
            put("request", new HashMap<>() {{
                put("subject", rmaSubject);
                put("comment", new HashMap<>() {{
                    put("html_body", getMailContent(model, recipient));
                    if (ObjectUtil.isNotEmpty(finalToken)) {
                        put("uploads", new String[]{finalToken});
                    }
                }});
                put("recipient", recipient);
                put("requester", new HashMap<>() {{
                    put("name", model.getName());
                    put("email", model.getMailAddress());
                }});
            }});
        }};
        return RestUtils.post(url, getAuthHeaders(), null, requestBody, JSONObject.class);
    }

    @NotNull
    private String getRecipientByRegionCode(@NotEmpty String regionCode) {
        // 查DB，暂时写死
        return regionCode + "@lexar.com";
    }

    private String getMailContent(WebSupportRmaRequest model, String recipient) {
        StringBuilder htmlMail = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(rmaMailTextUrl))) {
            String line;
            while ((line = reader.readLine()) != null) {
                htmlMail.append(line);
            }
        } catch (IOException e) {
            log.error("发生异常", e);
        }
        String[] params = new String[]{LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.NORM_DATETIME_PATTERN), model.getRegion(), model.getCountry(),
                model.getName(), model.getMailAddress(), model.getAddress(), model.getPhoneNo(),
                model.getProductType(), model.getProductSpeed(), model.getProductCapacity(),
                model.getPurchaseDate(), model.getQuantity(), model.getTroubles(), model.getIssue(), recipient};
        String formatContent = htmlMail.toString();
        for (int i = 0; i < params.length; i++) {
            formatContent = formatContent.replace("{" + i + "}", params[i]);
        }
        return formatContent;
    }

    private Map<String, String> getAuthHeaders() {
        Map<String, String> headers = new HashMap<>();
        String userCredentials = email + "/token:" + apiToken;
        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(userCredentials.getBytes());
        headers.put(HttpHeaders.AUTHORIZATION, basicAuth);
        return headers;
    }
}
